﻿//using Microsoft.EntityFrameworkCore;
//using Sgr.Domain.Entities;
//using Sgr.Domain.Uow;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Threading;
//using System.Threading.Tasks;

//namespace Sgr.Domain.Repositories
//{
//    /// <summary>
//    /// EF Core仓储扩展方法
//    /// </summary>
//    public static class Extensions
//    {
//        #region IMustHaveOrg

//        /// <summary>
//        /// 根据组织ID获取数据
//        /// </summary>
//        public static async Task<IEnumerable<TEntity>> GetByOrgIdAsync<TDbContext, TEntity, TPrimaryKey, TOrgKey>(
//            this EfCoreRepositoryOfTEntityAndTPrimaryKey<TDbContext, TEntity, TPrimaryKey> repository,
//            TOrgKey orgId,
//            CancellationToken cancellationToken = default)
//            where TEntity : class, IEntity<TPrimaryKey>, IAggregateRoot, IMustHaveOrg<TOrgKey>
//            where TDbContext : DbContext, IUnitOfWork
//        {
//            Check.NotNull(repository, nameof(repository));

//            return await repository.GetDbContext()
//                                 .Set<TEntity>()
//                                 .Where(f => f.OrgId!.Equals(orgId))
//                                 .ToArrayAsync(cancellationToken);
//        }

//        /// <summary>
//        /// 根据组织ID删除所有数据
//        /// </summary>
//        public static async Task DeleteByOrgIdAsync<TDbContext, TEntity, TPrimaryKey, TOrgKey>(
//            this EfCoreRepositoryOfTEntityAndTPrimaryKey<TDbContext, TEntity, TPrimaryKey> repository,
//            TOrgKey orgId,
//            CancellationToken cancellationToken = default)
//            where TEntity : class, IEntity<TPrimaryKey>, IAggregateRoot, IMustHaveOrg<TOrgKey>
//            where TDbContext : DbContext, IUnitOfWork
//        {
//            Check.NotNull(repository, nameof(repository));

//            var dbContext = repository.GetDbContext();
//            var entities = await dbContext.Set<TEntity>()
//                                        .Where(f => f.OrgId!.Equals(orgId))
//                                        .ToArrayAsync(cancellationToken);

//            dbContext.Set<TEntity>().RemoveRange(entities);
//            //await dbContext.SaveChangesAsync(cancellationToken);
//        }

//        #endregion IMustHaveOrg

//        #region IHaveCode

//        /// <summary>
//        /// 检查Code是否唯一
//        /// </summary>
//        /// <typeparam name="TDbContext">数据库上下文类型</typeparam>
//        /// <typeparam name="TEntity">实体类型</typeparam>
//        /// <typeparam name="TPrimaryKey">实体主键类型</typeparam>
//        /// <param name="repository">仓储实例</param>
//        /// <param name="code">代码</param>
//        /// <param name="id">当前实体ID,新增时可为空</param>
//        /// <param name="cancellationToken">取消令牌</param>
//        /// <returns>是否唯一</returns>
//        public static async Task<bool> CodeIsUniqueAsync<TDbContext, TEntity, TPrimaryKey>(
//            this EfCoreRepositoryOfTEntityAndTPrimaryKey<TDbContext, TEntity, TPrimaryKey> repository,
//            string code,
//            TPrimaryKey? id,
//            CancellationToken cancellationToken = default)
//            where TEntity : class, IEntity<TPrimaryKey>, IAggregateRoot, IHaveCode
//            where TDbContext : DbContext, IUnitOfWork
//        {
//            Check.NotNull(repository, nameof(repository));
//            Check.StringNotNullOrEmpty(code, nameof(code));

//            // 构建查询
//            var query = repository.GetDbContext()
//                                 .Set<TEntity>()
//                                 .AsNoTracking()
//                                 .Where(x => x.Code == code);

//            // 如果是编辑模式(id不为空),则排除自身
//            if (id != null && !id.Equals(default(TPrimaryKey)))
//            {
//                query = query.Where(x => !x.Id!.Equals(id));
//            }

//            // 检查是否存在相同Code的记录
//            return !await query.AnyAsync(cancellationToken);
//        }

//        #endregion IHaveCode

//        #region ISoftDelete

//        /// <summary>
//        /// 按照软删除的状态，获取所有数据
//        /// </summary>
//        /// <typeparam name="TDbContext">数据库上下文类型</typeparam>
//        /// <typeparam name="TEntity">实体类型</typeparam>
//        /// <typeparam name="TPrimaryKey">实体主键类型</typeparam>
//        /// <param name="repository">仓储实例</param>
//        /// <param name="isDeleted">是否已删除</param>
//        /// <param name="cancellationToken">取消令牌</param>
//        /// <returns>实体集合</returns>
//        public static async Task<IEnumerable<TEntity>> GetByDeletedStatusAsync<TDbContext, TEntity, TPrimaryKey>(
//            this EfCoreRepositoryOfTEntityAndTPrimaryKey<TDbContext, TEntity, TPrimaryKey> repository,
//            bool isDeleted,
//            CancellationToken cancellationToken = default)
//            where TEntity : class, IEntity<TPrimaryKey>, IAggregateRoot, ISoftDelete
//            where TDbContext : DbContext, IUnitOfWork
//        {
//            Check.NotNull(repository, nameof(repository));

//            return await repository.GetDbContext()
//                                 .Set<TEntity>()
//                                 .Where(f => f.IsDeleted == isDeleted)
//                                 .ToArrayAsync(cancellationToken);
//        }

//        /// <summary>
//        /// 物理删除
//        /// </summary>
//        /// <typeparam name="TDbContext">数据库上下文类型</typeparam>
//        /// <typeparam name="TEntity">实体类型</typeparam>
//        /// <typeparam name="TPrimaryKey">实体主键类型</typeparam>
//        /// <param name="repository">仓储实例</param>
//        /// <param name="entity">实体</param>
//        /// <returns>异步任务</returns>
//        public static void PhysicalDelete<TDbContext, TEntity, TPrimaryKey>(
//            this EfCoreRepositoryOfTEntityAndTPrimaryKey<TDbContext, TEntity, TPrimaryKey> repository,
//            TEntity entity)
//            where TEntity : class, IEntity<TPrimaryKey>, IAggregateRoot, ISoftDelete
//            where TDbContext : DbContext, IUnitOfWork
//        {
//            Check.NotNull(repository, nameof(repository));

//            var dbContext = repository.GetDbContext();
//            dbContext.Set<TEntity>().Remove(entity);

//            //await dbContext.SaveChangesAsync(cancellationToken);
//        }

//        /// <summary>
//        /// 恢复软删除的实体
//        /// </summary>
//        /// <typeparam name="TDbContext">数据库上下文类型</typeparam>
//        /// <typeparam name="TEntity">实体类型</typeparam>
//        /// <typeparam name="TPrimaryKey">实体主键类型</typeparam>
//        /// <param name="repository">仓储实例</param>
//        /// <param name="entity">实体</param>
//        /// <param name="cancellationToken">取消令牌</param>
//        /// <returns>异步任务</returns>
//        public static async Task RecoverAsync<TDbContext, TEntity, TPrimaryKey>(
//            this EfCoreRepositoryOfTEntityAndTPrimaryKey<TDbContext, TEntity, TPrimaryKey> repository,
//            TEntity entity,
//            CancellationToken cancellationToken = default)
//            where TEntity : class, IEntity<TPrimaryKey>, IAggregateRoot, ISoftDelete
//            where TDbContext : DbContext, IUnitOfWork
//        {
//            Check.NotNull(repository, nameof(repository));
//            Check.NotNull(entity, nameof(entity));

//            entity.IsDeleted = false;
//            await repository.UpdateAsync(entity, cancellationToken);
//        }

//        /// <summary>
//        /// 根据ID恢复软删除的实体
//        /// </summary>
//        /// <typeparam name="TDbContext">数据库上下文类型</typeparam>
//        /// <typeparam name="TEntity">实体类型</typeparam>
//        /// <typeparam name="TPrimaryKey">实体主键类型</typeparam>
//        /// <param name="repository">仓储实例</param>
//        /// <param name="id">实体ID</param>
//        /// <param name="cancellationToken">取消令牌</param>
//        /// <returns>异步任务</returns>
//        public static async Task RecoverAsync<TDbContext, TEntity, TPrimaryKey>(
//            this EfCoreRepositoryOfTEntityAndTPrimaryKey<TDbContext, TEntity, TPrimaryKey> repository,
//            TPrimaryKey id,
//            CancellationToken cancellationToken = default)
//            where TEntity : class, IEntity<TPrimaryKey>, IAggregateRoot, ISoftDelete
//            where TDbContext : DbContext, IUnitOfWork
//        {
//            Check.NotNull(repository, nameof(repository));

//            var entity = await repository.GetAsync(id, cancellationToken);
//            if (entity != null)
//            {
//                await RecoverAsync(repository, entity, cancellationToken);
//            }
//        }

//        #endregion ISoftDelete
//    }
//}